﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Galaktika.BI.Charting;
using Galaktika.BI.Extensibility.Dom;
using Galaktika.BI.Extensibility.Json;
using Galaktika.BI.Runtime.Services;
using Galaktika.BI.Silverlight.Controls.OLAP.Descriptions;
using Galaktika.BI.Silverlight.Intermediate.Charting;
using Ranet.Olap.Core.Data;
using Galaktika.BI.Silverlight.Controls.Data;

namespace Galaktika.BI.Silverlight.Controls
{
    public partial class Selector : ComboBox, IBindableObject, IEditableObject
    {
        private bool m_FirstLoad = true;
        private ComboBox cbox;

        public Selector()
        {           
            //InitializeComponent();
            cbox = this;
            cbox.SelectionChanged += new SelectionChangedEventHandler(cbox_SelectedIndexChanged);
            this.IsEnabled = false;
            this.IsMouseWheelAttached = false;
            Galaktika.BI.Silverlight.MemoryProfiler.AddReference(this);
        }
              
        private object m_DataSource;
        [Browsable(false)]
        public object ADataSource
        {
            get
            {
                return m_DataSource;
            }
            set
            {
                m_DataSource = value;                
            }
        }

        private string m_Variable = string.Empty;
        [Browsable(false)]
        public string AVariable
        {
            get { return m_Variable; }
            set 
            { 
                m_Variable = value;
            }
        }

        private string m_Path = string.Empty;
        [Browsable(false)]
        public string APath
        {
            get { return m_Path; }
            set { m_Path = value; }
        }

        private string m_NameItem = string.Empty;
        [Browsable(false)]
        public string ANameItem
        {
            get { return m_NameItem; }
            set { m_NameItem = value; }
        }

        private string m_ValueItem = string.Empty;
        [Browsable(false)]
        public string AValueItem
        {
            get { return m_ValueItem; }
            set { m_ValueItem = value; }
        }

        public bool IsMouseWheelAttached { get; set; }

        protected override void OnGotFocus(RoutedEventArgs e)
        {
            base.OnGotFocus(e);
            if (!this.IsMouseWheelAttached)
            {
                this.AddMouseWheelSupport();
            }
        }
       
        public ScrollViewer GetScroller()
        {            
            return base.GetTemplateChild("ElementScrollViewer") as ScrollViewer;
        }

        #region IBindableObject Members

        private IBindingContext m_Context;
        public IBindingContext Context
        {
            get
            {
                return m_Context;
            }
            set
            {
                m_Context = value;                
            }
        }

        private Dictionary<string, IBindingManager> m_Bindings;
        public IDictionary<string, IBindingManager> Bindings
        {
            get
            {
                if (m_Bindings == null)
                {
                    m_Bindings = new Dictionary<string, IBindingManager>();
                }

                return m_Bindings;
            }
        }

        #endregion

        private void PopulateItems(BrickVariable var)
        {
            cbox.Items.Clear();
            if (var != null)
            {
                // TODO: navigate using Path
                // TODO: consume JsonObject too
                using (JsonParser parser = new JsonParser(new StringReader(var.Value), true))
                {
                    JsonArray array = parser.ParseArray();
                    for (int i = 0; i < array.Count; i++)
                    {
                        JsonObject obj = (JsonObject)array[i];
                        ComboBoxItem item = new ComboBoxItem()
                                                {
                                                    Content = obj[m_NameItem].ToString(),
                                                    Tag = obj[m_ValueItem].ToString()
                                                };                           
                        cbox.Items.Add(item);
                    }
                }
            }
        }

        private void SetDefaultValue(BrickVariable var)
        {
            if (var != null)
            {
                using (JsonParser parser = new JsonParser(new StringReader(var.Value), true))
                {
                    JsonArray array = parser.ParseArray();
                    for (int i = 0; i < array.Count; i++)
                    {
                        JsonObject obj = (JsonObject)array[i];
                        string val = obj[m_ValueItem].ToString();
                        if (val == var.DefaultValue)
                        {
                            if ((cbox.SelectedItem == null) || ((cbox.SelectedItem as ComboBoxItem).Tag.ToString() != val))
                            {
                                cbox.SelectedItem = cbox.Items[i];
                            }
                            break;
                        }
                    }
                }
            }
        }
       
        private void cbox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (m_Context != null)
            {                
                IExecutionContext exe = (IExecutionContext)m_Context.Services.GetService(typeof(IExecutionContext));
                IUserTaskManager taskManager = (IUserTaskManager)m_Context.Services.GetService(typeof(IUserTaskManager));                
                if (exe != null && taskManager != null)
                {
                    //TODO: Асинхронно
                    var item = (cbox.SelectedItem as ComboBoxItem).Tag.ToString();
                    taskManager.RunTaskAsync(String.Format(Localization.AppTask_ExecutingServiceCommand,"ModifyVariable"), state=>
                                                                                                                               {
                                                                                                                                   exe.ModifyVariable(m_Context, m_Variable, item);
                                                                                                                               });                    
                }
                
            }
        }

        #region IEditableObject Members

        public void BeginEdit()
        {
        }

        public void CancelEdit()
        {
        }

        public void EndEdit()
        {
            if (this.m_FirstLoad)
            {
                this.m_FirstLoad = false;

                IExecutionContext exec = (IExecutionContext)m_Context.Services.GetService(typeof(IExecutionContext));
                IUserTaskManager taskManager = (IUserTaskManager)m_Context.Services.GetService(typeof(IUserTaskManager));
                if (exec != null && taskManager !=null && this.ADataSource == null)
                {
                    //TODO: Асинхронно
                    taskManager.RunTaskAsync(String.Format(Localization.AppTask_ExecutingServiceCommand,"GetVariable"),state=>
                                                                                                                           {
                                                                                                                               BrickVariable var = exec.GetVariable(m_Context, m_Variable);
                                                                                                                               taskManager.Dispatcher.BeginInvoke(()=>
                                                                                                                                                                      {
                                                                                                                                                                          this.PopulateItems(var);
                                                                                                                                                                          this.SetDefaultValue(var);
                                                                                                                                                                          this.IsEnabled = true;
                                                                                                                                                                      });
                                                                                                                           });                                        
                }

                if (!this.IsEnabled)
                    this.IsEnabled = true;
                this.PopulateItems(this.m_DataSource);
            }
        }
        #endregion

        private void PopulateItems(object dataSource)
        {
            if (dataSource == null)
            {
                return;
            }

            cbox.Items.Clear();
            if (dataSource is CellSetData)
            {                
                var data = this.ADataSource as CellSetData;
                int i = 0;
                foreach (var rows in data.Axes[0].Positions)
                {
                    int j = 0;
                    FlatDescriptionCollection source = new FlatDescriptionCollection();
                    foreach (var columns in data.Axes[1].Positions)
                    {

                        FlatDescription obj = new FlatDescription();
                        if (!String.IsNullOrEmpty(columns.Members[0].Caption))
                        {                            
                            obj.Argument = columns.Members[0].Caption;
                            var value = data.GetCellDescription(i, j).Value.Value;
                            obj.DisplayValue = value;
                            source.Add(obj);
                            ComboBoxItem item = new ComboBoxItem();
                            item.Content = obj.Argument;
                            item.Tag = obj.DisplayValue;
                            cbox.Items.Add(item);
                        }
                        j++;
                    }
                    i++;
                }

                cbox.SelectedIndex = 0;
                //dataSource = (dataSource as CellSetData).FlatData;
            }

            if (dataSource is DataTableWrapper)
            {
                var data = dataSource as DataTableWrapper;
                TestData[] bindCollection = new TestData[data.RowCount];
                int i = 0;
                int j = 0;
                for (j = 0; j < data.RowCount; j++)
                {
                    var bindObject =
                    new TestData() { First = data.Items[i], Second = Convert.ToInt32(data.Items[i+1]) };
                    i += 2;
                    bindCollection[j] = bindObject;
                    ComboBoxItem item = new ComboBoxItem();
                    item.Content = bindObject.First;
                    item.Tag = bindObject.Second.ToString();
                    cbox.Items.Add(item);
                }
                cbox.SelectedIndex = 0;
                //foreach (DataTableColumnDefinition row in (dataSource as DataTableWrapper).Columns)
                //{
                    
                //    PropertyDescriptor descriptorValue = TypeDescriptor.GetProperties(row)[m_ValueItem];
                //    PropertyDescriptor descriptorName = TypeDescriptor.GetProperties(row)[m_NameItem];
                //    if ((descriptorValue != null) && ((descriptorName != null)))
                //    {
                //        ComboBoxItem item = new ComboBoxItem(
                //            descriptorName.GetValue(row).ToString(),
                //            descriptorValue.GetValue(row).ToString());
                //        cbox.Items.Add(item);
                //    }
                //}
            }

            //cbox.SelectedIndex = 0;
        }    
    }
}
